﻿using Infrastructures;
using Models;
using Newtonsoft.Json.Linq;
using Spring.Data.Common;
using Spring.Data.Generic;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RepositoryMySQL
{
    internal class QueryHelper
    {
        internal static IList<IDictionary<string, string>> Query(string sql, IDbParameters p, Func<IDataReader, int, IDictionary<string, string>> func = null)
        {
            return DBHelper.TemplateMySQL.QueryWithRowMapperDelegate(CommandType.Text, sql, new RowMapperDelegate<IDictionary<string, string>>(func == null ? MapRow : func), p);
        }

        internal static IList<IDictionary<string, string>> Query(string sql, Func<IDataReader, int, IDictionary<string, string>> func = null)
        {
            return DBHelper.TemplateMySQL.QueryWithRowMapperDelegate(CommandType.Text, sql, new RowMapperDelegate<IDictionary<string, string>>(func == null ? MapRow : func));
        }

        internal static ModelList<IDictionary<string, string>> QueryPaging(string sql, IDbParameters p, Func<IDataReader, int, IDictionary<string, string>> func = null)
        {
            ModelList<IDictionary<string, string>> lst = new ModelList<IDictionary<string, string>>();

            DBHelper.TemplateMySQL.QueryWithRowCallbackDelegate(CommandType.Text, sql, (dr) =>
            {
                lst.Add(func == null ? MapRow(dr, 0) : func(dr, 0));

                while (dr.Read())
                    lst.Add(func == null ? MapRow(dr, 0) : func(dr, 0));

                bool isNext = dr.NextResult();

                while (dr.Read() && isNext)
                    lst.TotalCount = dr.GetInt32(0);

            }, p);

            return lst;
        }

        internal static JObject QueryJson(string sql, Func<IDataReader, int, IDictionary<string, string>> func = null)
        {
            var lst = DBHelper.TemplateMySQL.QueryWithRowMapperDelegate(CommandType.Text, sql, new RowMapperDelegate<IDictionary<string, string>>(func == null ? MapRow : func));
            JObject json = new JObject();
            json["data"] = JValue.FromObject(lst);

            return json;
        }

        internal static JObject QueryJson(string sql, IDbParameters p, Func<IDataReader, int, IDictionary<string, string>> func = null)
        {
            var lst = DBHelper.TemplateMySQL.QueryWithRowMapperDelegate(CommandType.Text, sql, new RowMapperDelegate<IDictionary<string, string>>(func == null ? MapRow : func), p);
            JObject json = new JObject();
            json["data"] = JValue.FromObject(lst);

            return json;
        }

        internal static JObject QueryPagingJson(string sql, IDbParameters p, Func<IDataReader, int, IDictionary<string, string>> func = null)
        {
            ModelList<IDictionary<string, string>> lst = new ModelList<IDictionary<string, string>>();

            DBHelper.TemplateMySQL.QueryWithRowCallbackDelegate(CommandType.Text, sql, (dr) =>
            {
                lst.Add(func == null ? MapRow(dr, 0) : func(dr, 0));

                while (dr.Read())
                    lst.Add(func == null ? MapRow(dr, 0) : func(dr, 0));

                bool isNext = dr.NextResult();

                while (dr.Read() && isNext)
                    lst.TotalCount = dr.GetInt32(0);

            }, p);

            JObject json = new JObject();
            json["data"] = JValue.FromObject(lst);
            json["count"] = lst.TotalCount;

            return json;
        }

        private static IDictionary<string, string> MapRow(IDataReader dr, int count)
        {
            IDictionary<string, string> dic = new Dictionary<string, string>();
            int col = dr.FieldCount;
            for (int i = 0; i < col; i++)
            {
                dic.Add(dr.GetName(i), dr.GetValue(i).ToString());
            }

            return dic;
        }
    }
}
